-----------
-- Component simply chooses the right PC to store in a register
----
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity PC_UNIT is

	PORT (
	CLK : in STD_LOGIC;
	
	PC_BRANCH_IN : in STD_LOGIC_VECTOR(31 downto 0); -- Input from branched position
	PC_SEQUENTIAL_IN : in STD_LOGIC_VECTOR(31 downto 0); -- the next PC, in sequtential order
	PC_IS_BRANCH_IN : in STD_LOGIC; -- was there a branch somewhere down the pipeline?
	PC_JUMP_IN : in STD_LOGIC_VECTOR(31 downto 0); -- jump full addr
	PC_IS_JUMP_IN : in STD_LOGIC; -- was there a jump?
	
	STALL_FROM_DECODE : in STD_LOGIC; -- stall signal originating from decode.
	
	PC_OUT : out STD_LOGIC_VECTOR(31 downto 0)
	);
	
end PC_UNIT;

architecture Behavioral of PC_UNIT is
	signal PC_STORAGE : STD_LOGIC_VECTOR(31 downto 0)  := x"00400000"; -- start at PC = 0x0004000
begin

	PC_OUT <= PC_STORAGE;

	process(CLK) 
	begin	
		if (CLK'event and CLK = '1') then
			if (PC_IS_JUMP_IN = '1') then
				PC_STORAGE <= PC_JUMP_IN;
			elsif (PC_IS_BRANCH_IN = '1') then
				PC_STORAGE <= PC_BRANCH_IN;
			else
				if (STALL_FROM_DECODE = '0') then -- Only update the buffer when there is no stall (assuming there is no branch/jmp)
					PC_STORAGE <= PC_SEQUENTIAL_IN;
				end if;
			end if;		
		end if;
	end process;


end Behavioral;

